/* 
 * File:   GraphicsCore.h
 * Author: RedEyedKiller
 *
 * Created on 20 Ιούλιος 2011, 6:03 πμ
 */

#ifndef GRAPHICSCORE_H
#define	GRAPHICSCORE_H

#include "Screen.h"
#include "Canvas.h"
#include "TextureCoords.h"
#include "GLColor.h"
#include "Texture.h"
#include "../Rect.h"
#include "Vertex.h"
#include "GLSLExtension.h"
#include "BlendingMethodManager.h"

#include <list>
#include <string>

namespace sdl
{

class GraphicsCore : public NonCopyable
{
public:
    
    GraphicsCore()
	{
		mainScreen = NULL;
		sdlScreen = NULL;
	}
    
    ~GraphicsCore();
    
    /**
     * Via this method screens and frame buffer is initialized.
     * 
     * @param screenW 
     * @param screenH 
     * @param bpp
     * @param fullscreen
     * @param useSdlScreen
     * @return 
     */
    bool Initialize(int screenW, int screenH, int bpp, bool fullscreen,bool useSdlScreen);
    
    /**
     * The main method of graphics core. This renders the specified arguments onto the
     * screen as a quad polygon.
     * 
     * @param texture 
     * @param clip 
     * @param color  
     * @param position 
     * @param scale
     * @param angle in degrees and clockwise
     * @param flip
     * @return 
     */
    bool Render(const gl::Texture& texture,const Math::Rect& clip,const gl::Color& color,
        const Math::Vector2F& position,const Math::Vector2F& scale,float angle,bool flip[],gl::BlendingMethodName blend = gl::BLEND_ALPHA);
    
    bool DrawLine(const Math::Vector2F& start,const Math::Vector2F& end,const gl::Color& color);
    
    bool DrawRect(const Math::Vector2F& start,const Math::Vector2F& end,const gl::Color& color);
    
    /**
     * Instruct the GraphicsCore that the rendering process will begin.
     * @return true in success
     */
    bool BeginRendering();
    
    /**
     * Inform the GraphicsCore that no more objects will be rendered.
     * @return true in success
     */
    bool EndRendering();
    
    /**
     * Ckecks if name opengl extension exists.
     * @param name
     * @return 
     */
    bool CheckForExtension(const char* name);
    
    void CreateExtensionList();
   
    Canvas* GetSdlScreen() const;
    
    Screen* GetGlScreen() const;
protected:
    /**
     * Creates the texture coordeinates to map the given portion of the texture onto the quad.
     * @param tCoords
     * @param texture
     * @param clip
     * @param flip
     */
    void TextureCoordinates(gl::TextureCoords tCoords[4],const gl::Texture& texture,const Math::Rect& clip,bool flip[]) const;
    
    /**
     * Initializes the given vertices to the correct xy.
     * 
     * @param vertecies
     * @param position
     * @param clip
     * @param scale
     */
    void Transorm(gl::Vertex vertecies[4], const Math::Vector2F& position, const Math::Rect& clip, const Math::Vector2F& scale) const;
    
    /**
     * Called by Initialize to set opengl const before initializing the framebuffer.
     */
    void SetOpenglConstants();
private:
    
    /**
     * The frame buffer of the engine.
     */
    Screen* mainScreen;
    
    /**
     * If the screen is in opengl mode this canvas is used for sdl functionality.
     */
    Canvas* sdlScreen;
    
    /**
     * The manager tha keeps track of different blending methods.
     */
    gl::BlendingMethodManager blengingMethods;
    
    /**
     * A list with all the names of the supported opengl extensions.
     */
    std::list<std::string> extensionList;
};
};

#endif	/* GRAPHICSCORE_H */

